#include "GFuns.h"
#include <math.h>
#include <vector>
using namespace std;

vector<int> currentRands;

void PushRand(int aRand)
{
	currentRands.push_back(aRand);
	srand(aRand);
}

int PopRand()
{
	int rand = currentRands.back();
	currentRands.pop_back();
	return rand;
}

string iToString(int i)
{
	char value[20];
	_itoa(i,value,10);
	return value;
}

void draw_rectangle(float aX1, float aY1, float aX2, float aY2, ALLEGRO_COLOR aFill, ALLEGRO_COLOR aBord, float aThik){
	al_draw_filled_rectangle(aX1,aY1,aX2,aY2,aFill);
	al_draw_rectangle(aX1,aY1,aX2,aY2,aBord,aThik);
}

void draw_rounded_rectangle(float aX1, float aY1, float aX2, float aY2, float aRX, float aRY, ALLEGRO_COLOR aFill, ALLEGRO_COLOR aBord, float aThik){
	al_draw_filled_rounded_rectangle(aX1,aY1,aX2,aY2,aRX,aRY,aFill);
	al_draw_rounded_rectangle(aX1,aY1,aX2,aY2,aRX,aRY,aBord,aThik);
}

void draw_triangle(float aX1, float aY1, float aX2, float aY2, float aX3, float aY3, ALLEGRO_COLOR aFill, ALLEGRO_COLOR aBord, float aThik){
	al_draw_filled_triangle(aX1,aY1,aX2,aY2,aX3,aY3,aFill);
	al_draw_triangle(aX1,aY1,aX2,aY2,aX3,aY3,aBord,aThik);
}

void draw_ellipse(float aCX, float aCY, float aRX, float aRY, ALLEGRO_COLOR aFill, ALLEGRO_COLOR aBord, float aThik){
	al_draw_filled_ellipse(aCX,aCY,aRX,aRY,aFill);
	al_draw_ellipse(aCX,aCY,aRX,aRY,aBord,aThik);
}

void draw_quad(Node verts[4], ALLEGRO_COLOR aFill, ALLEGRO_COLOR aBord, float aThik){
	al_draw_filled_triangle(verts[0].x,verts[0].y,verts[1].x,verts[1].y,verts[2].x,verts[2].y,aFill);
	al_draw_filled_triangle(verts[3].x,verts[3].y,verts[1].x,verts[1].y,verts[2].x,verts[2].y,aFill);

	al_draw_line(verts[0].x,verts[0].y,verts[1].x,verts[1].y,aBord,aThik);
	al_draw_line(verts[1].x,verts[1].y,verts[3].x,verts[3].y,aBord,aThik);
	al_draw_line(verts[3].x,verts[3].y,verts[2].x,verts[2].y,aBord,aThik);
	al_draw_line(verts[2].x,verts[2].y,verts[0].x,verts[0].y,aBord,aThik);
}


double randNorm(){
	int sum = 0;
	for(int i=0; i<3; i++){
		sum+=rand()%101+1;
	}
	sum/=3.0;
	sum-=50;
	return abs(sum/50.0);
}

bool eq(ALLEGRO_COLOR aCol1, ALLEGRO_COLOR aCol2){
	if(aCol1.r == aCol2.r)
		if(aCol1.g == aCol2.g)
			if(aCol1.b == aCol2.b)
				if(aCol1.a == aCol2.a)
					return true;
	return false;
}

double randInterval(double aBegin, double aEnd){
	return aBegin + ((rand()%1000)*(aEnd-aBegin))/1000.0;
}

int randInt(int aBegin, int aEnd){
	if(aBegin>=aEnd) return aEnd;
	return aBegin + rand()%(aEnd-aBegin+1);
}

void drawLine(Node aN1, Node aN2, ALLEGRO_COLOR aCl, int aThik){
	al_draw_line(aN1.x,aN1.y,aN2.x,aN2.y,aCl,aThik);
}

void drawRect(sRectangle aRect, ALLEGRO_COLOR aFillCol, ALLEGRO_COLOR aBordCol, int aThick){
	al_draw_filled_rectangle(aRect.x1,aRect.y1,aRect.x2,aRect.y2,aFillCol);
	al_draw_rectangle(aRect.x1,aRect.y1,aRect.x2,aRect.y2,aBordCol,aThick);
}

void drawRect(sRectangle aRect, ALLEGRO_COLOR aBordCol, int aThick){
	al_draw_rectangle(aRect.x1,aRect.y1,aRect.x2,aRect.y2,aBordCol,aThick);
}

void drawRect(sRectangle aRect, ALLEGRO_COLOR aFillCol){
	al_draw_filled_rectangle(aRect.x1,aRect.y1,aRect.x2,aRect.y2,aFillCol);
}

void drawGradient(float x1, float y1, float x2, float y2, ALLEGRO_COLOR c1, ALLEGRO_COLOR c2){
  ALLEGRO_VERTEX v[] ={
		{ x1, y1, 0, 0, 0, c1},
		{ x2, y1, 0, 0, 0, c1},
		{ x1, y2, 0, 0, 0, c2},
		{ x2, y2, 0, 0, 0, c2}};
   al_draw_prim(v, NULL, NULL, 0, 4, ALLEGRO_PRIM_TRIANGLE_STRIP);
}

void drawDirectLine(float& aX, float& aY, float aLen, float aDir, ALLEGRO_COLOR aColor, float aThik, bool aOverwrite){
	al_draw_line(aX,aY,aX-aLen*cos(aDir),aY-aLen*sin(aDir),aColor,aThik);
	if(aOverwrite){
		aX = aX-aLen*cos(aDir);
		aY = aY-aLen*sin(aDir);
	}
}

void drawAlphaBitmap(ALLEGRO_BITMAP* aBitmap, unsigned char aAlpha, float aX, float aY, float aFlags){
	al_draw_tinted_bitmap(aBitmap,al_map_rgba(255+aAlpha,255+aAlpha,255+aAlpha,aAlpha),aX,aY,aFlags);
}

void drawScaledAlphaBitmap(ALLEGRO_BITMAP* aBitmap, unsigned char aAlpha, float aSX, float aSY, float aSW, float aSH,
	float aDX, float aDY, float aDW, float aDH, float aFlags )
{
	al_draw_tinted_scaled_bitmap(aBitmap,al_map_rgba(255+aAlpha,255+aAlpha,255+aAlpha,aAlpha),aSX,aSY,aSW,aSH,aDX,aDY,aDW,aDH,aFlags);
}

void noise(ALLEGRO_COLOR aCol1, ALLEGRO_COLOR aCol2, int aProb){
	ALLEGRO_BITMAP* disp = al_get_target_bitmap();
	int w = al_get_bitmap_width(disp);
	int h = al_get_bitmap_height(disp);

	al_lock_bitmap(disp,al_get_bitmap_format(disp),ALLEGRO_LOCK_READWRITE);
	for(int x=0; x<w; x++)
		for(int y=0; y<h; y++){
			if(rand()%aProb == 0 && (eq(al_get_pixel(disp,x,y),aCol1))) al_put_pixel(x,y,aCol2);
		}
	al_unlock_bitmap(disp);
}

void blur(ALLEGRO_BITMAP* aIn, ALLEGRO_BITMAP* aOut){
	int range = 32;

	float alpha = 1.0/100.0;
	ALLEGRO_COLOR color = al_map_rgba_f(alpha, alpha, alpha, alpha);
	int w = al_get_bitmap_width(aIn);
	int h = al_get_bitmap_height(aIn);

	al_set_target_bitmap(aOut);
	for (int y = -range; y <= range; y++) {
		for (int x = -range; x <= range; x++) {
			if (sqrt((double)(x*x+y*y)) <= 10)
				al_draw_tinted_bitmap_region(aIn, color, x, y, w, h, 0, 0, 0);
		}
	}
}

/*Node getSplinePoint(float x1, float y1, float x2, float y2, float aLen, bool aPos){
	float dx = x1-x2;
	float dy = y2-y1;
	float a = atan2(dx,dy);

	if(aPos) a+=3.14/2.0;

	float x3 = (x1+x2)/2.0;
	float y3 = (y1+y2)/2.0;

	Node r = {x3 - aLen*cos(a),y3 - aLen*sin(a)};
	return r;
}*/